home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
lineed.zip
/
ANSI.C
< prev
next >
Wrap
Text File
|
1992-04-05
|
20KB
|
848 lines
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
* to initialize:
* call set_screensize(<# lines to reserve>);
* to print through ansi interpreter:
* call ansi(<string>);
*/
char curattr = 7;
int curx = 0,cury = 0;
int topx = 0,topy = 0; /* offset "down" to window */
int fakemaxx = 80, fakemaxy = 25; /* size of ansi output window */
int maxy,maxx; /* real screen size */
char useansi = 1; /* while true, interp ansi seqs */
int tabspaces = 8;
static int savx,savy,issaved = 0;
static char ansi_terminators[] = "HFABCDnsuJKmp";
#ifdef __TURBOC__
#define _fastcall pascal
#endif
#define MAXARGLEN 128
#define NOTHING 0
#define WASESCAPE 1
#define WASBRKT 2
/* set fakemaxx,fakemaxy as desired */
void _fastcall set_screensize (int reservedbotlines,int reservedtoplines);
/* put character c at x,y using attr as attribute */
void _fastcall put_char (char c,char attr,int x,int y);
/* position hardware cursor at x,y */
void _fastcall pos_hardcursor (int x,int y);
/* turn hardware cursor off */
void _fastcall hardcursor_off (void);
/* turn hardware cursor on at x,y */
void _fastcall hardcursor_on (int x,int y);
/* scroll window tx,ty - bx,by up one line; fill with blank+attr */
void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr);
/* clear the window from tx,ty - bx,by; fill with blank+attr */
void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr);
/* clear line y from col x to eol (ex); fill with blank+attr */
void _fastcall cleartoeol (int x,int y,int ex,char attr);
/* validate cursor position after external routines may have changed it */
void _fastcall validate_cursor (void);
/* get current cursor position */
void _fastcall get_hardcursorpos (int *x,int *y);
/* printf replacement through ansi string interpreter */
int aprintf(char *str,...);
/* the ansi string interpreter */
int _fastcall ansi (char *buf);
/* "generic" support functions closely related to ansi */
void _fastcall set_pos (char *argbuf,int arglen,char cmd) {
int y,x;
char *p;
if(!*argbuf || !arglen) {
curx = topx;
cury = topy;
}
y = atoi(argbuf) - 1;
p = strchr(argbuf,';');
if(y >= 0 && p) {
x = atoi(p + 1) - 1;
if(x >= 0) {
curx = x;
cury = y;
curx += topx;
cury += topy;
if(curx > (fakemaxx + topx) - 1)
curx = (fakemaxx + topx) - 1;
if(cury > (fakemaxy + topy) - 1)
cury = (fakemaxy + topy) - 1;
}
}
}
void _fastcall go_up (char *argbuf,int arglen,char cmd) {
int x;
x = atoi(argbuf);
if(!x) x = 1;
for(;x;x--) {
if(cury <= topy) break;
cury--;
}
}
void _fastcall go_down (char *argbuf,int arglen,char cmd) {
int x;
x = atoi(argbuf);
if(!x) x = 1;
for(;x;x--) {
if(cury == (fakemaxy + topy) - 1) break;
cury++;
}
}
void _fastcall go_left (char *argbuf,int arglen,char cmd) {
int x;
x = atoi(argbuf);
if(!x) x = 1;
for(;x;x--) {
if(curx <= topx) break;
curx--;
}
}
void _fastcall go_right (char *argbuf,int arglen,char cmd) {
int x;
x = atoi(argbuf);
if(!x) x = 1;
for(;x;x--) {
if(curx == (fakemaxx + topx) - 1) break;
curx++;
}
}
void _fastcall report (char *argbuf,int arglen,char cmd) {
/* you figure out how to implement it ... */
}
void _fastcall save_pos (char *argbuf,int arglen,char cmd) {
savx = curx;
savy = cury;
issaved = 1;
}
void _fastcall restore_pos (char *argbuf,int arglen,char cmd) {
if(issaved) {
curx = savx;
cury = savy;
issaved = 0;
}
}
void _fastcall clear_screen (char *argbuf,int arglen,char cmd) {
/* needs error checking */
clearwindow(topx,topy,(fakemaxx + topx) - 1,(fakemaxy + topy) - 1,curattr);
curx = topx;
cury = topy;
}
void _fastcall kill_line (char *argbuf,int arglen,char cmd) {
cleartoeol(curx + topx,cury + topy,(fakemaxx + topx) - 1,curattr);
}
void _fastcall set_ansicolors (char *argbuf,int arglen,char cmd) {
char *p,*pp;
if(*argbuf && arglen) {
pp = argbuf;
do {
p = strchr(pp,';');
if(p && *p) {
*p = 0;
p++;
}
switch(atoi(pp)) {
case 0: /* all attributes off */
curattr = 7;
break;
case 1: /* bright on */
curattr |= 8;
break;
case 2: /* faint on */
curattr &= (~8);
break;
case 3: /* italic on */
break;
case 5: /* blink on */
curattr |= 128;
break;
case 6: /* rapid blink on */
break;
case 7: /* reverse video on */
curattr = 112;
break;
case 8: /* concealed on */
curattr = 0;
break;
case 30: /* black fg */
curattr &= (~7);
break;
case 31: /* red fg */
curattr &= (~7);
curattr |= 4;
break;
case 32: /* green fg */
curattr &= (~7);
curattr |= 2;
break;
case 33: /* yellow fg */
curattr &= (~7);
curattr |= 6;
break;
case 34: /* blue fg */
curattr &= (~7);
curattr |= 1;
break;
case 35: /* magenta fg */
curattr &= (~7);
curattr |= 5;
break;
case 36: /* cyan fg */
curattr &= (~7);
curattr |= 3;
break;
case 37: /* white fg */
curattr |= 7;
break;
case 40: /* black bg */
curattr &= (~112);
break;
case 41: /* red bg */
curattr &= (~112);
curattr |= (4 << 4);
break;
case 42: /* green bg */
curattr &= (~112);
curattr |= (2 << 4);
break;
case 43: /* yellow bg */
curattr &= (~112);
curattr |= (6 << 4);
break;
case 44: /* blue bg */
curattr &= (~112);
curattr |= (1 << 4);
break;
case 45: /* magenta bg */
curattr &= (~112);
curattr |= (5 << 4);
break;
case 46: /* cyan bg */
curattr &= (~112);
curattr |= (3 << 4);
break;
case 47: /* white bg */
curattr |= 112;
break;
case 48: /* subscript bg */
break;
case 49: /* superscript bg */
break;
default: /* unsupported */
break;
}
pp = p;
} while(p);
}
}
int aprintf (char *str,...) {
va_list ap;
static char buffer[513];
va_start (ap, str);
vsprintf (buffer, str, ap);
va_end (ap);
return ansi(buffer);
}
int _fastcall ansi (char *buf) {
int arglen = 0,ansistate = NOTHING,x;
char *b = buf,argbuf[MAXARGLEN] = "";
{ /* match our pos to hardware cursor's pos */
get_hardcursorpos(&curx,&cury);
if(curx > (fakemaxx + topx) - 1)
curx = (fakemaxx + topx) - 1;
if(cury > (fakemaxy + topy) - 1)
cury = (fakemaxy + topy) - 1;
}
hardcursor_off();
if(!useansi) { /* is ANSI interp on? */
ansistate = NOTHING;
arglen = 0;
*argbuf = 0;
}
while(*b) {
switch(ansistate) {
case NOTHING:
switch(*b) {
case '\x1b':
if(useansi) {
ansistate = WASESCAPE;
break;
}
case '\r': /* C-like inp of \n (and \r) sorta */
/* curx = topx;
break; */
case '\n':
curx = topx;
cury++;
if(cury > (fakemaxy + topy) - 1) {
scroll_up(topx,topy,(fakemaxx + topx) - 1,(fakemaxy + topy) - 1,curattr);
cury--;
}
break;
case '\t': /* so _you_ figure out what to do... */
for(x = 0;x < tabspaces;x++) {
put_char(' ',curattr,curx + topx,cury + topy);
curx++;
if(curx > (fakemaxx + topx) - 1) {
curx = topx;
cury++;
if(cury > fakemaxy - 1) {
scroll_up(topx,topy,(fakemaxx + topx) - 1,(fakemaxy + topy) - 1,curattr);
cury--;
}
}
}
break;
case '\b':
if(curx > topx) {
curx--;
}
break;
case '\07': /* usually a console bell */
putchar('\07');
break;
default:
put_char(*b,curattr,curx + topx,cury + topy);
curx++;
if(curx > (fakemaxx + topx) - 1) {
curx = topx;
cury++;
if(cury > fakemaxy - 1) {
scroll_up(topx,topy,(fakemaxx + topx) - 1,(fakemaxy + topy) - 1,curattr);
cury--;
}
}
break;
}
break;
case WASESCAPE:
if(*b == '[') {
ansistate = WASBRKT;
arglen = 0;
*argbuf = 0;
break;
}
ansistate = NOTHING;
break;
case WASBRKT:
if(strchr(ansi_terminators,(int)*b)) {
switch((int)*b) {
case 'H': /* set cursor position */
case 'F':
set_pos(argbuf,arglen,*b);
break;
case 'A': /* up */
go_up(argbuf,arglen,*b);
break;
case 'B': /* down */
go_down(argbuf,arglen,*b);
break;
case 'C': /* right */
go_right(argbuf,arglen,*b);
break;
case 'D': /* left */
go_left(argbuf,arglen,*b);
break;
case 'n': /* report pos */
report(argbuf,arglen,*b);
break;
case 's': /* save pos */
save_pos(argbuf,arglen,*b);
break;
case 'u': /* restore pos */
restore_pos(argbuf,arglen,*b);
break;
case 'J': /* clear screen */
clear_screen(argbuf,arglen,*b);
break;
case 'K': /* delete to eol */
kill_line(argbuf,arglen,*b);
break;
case 'm': /* set video attribs */
set_ansicolors(argbuf,arglen,*b);
break;
case 'p': /* keyboard redef -- disallowed */
break;
default: /* unsupported */
break;
}
ansistate = NOTHING;
arglen = 0;
*argbuf = 0;
}
else {
if(arglen < MAXARGLEN) {
argbuf[arglen] = *b;
argbuf[arglen + 1] = 0;
arglen++;
}
}
break;
default:
pos_hardcursor(curx + topx,cury + topy);
fputs("\n **Error in ANSI state machine.\n",stderr);
break;
}
b++;
}
pos_hardcursor(curx + topx,cury + topy);
hardcursor_on(curx + topx,cury + topy);
return ((int)b - (int)buf);
}
/* OS specific functions -- this can be moved to a separate module */
#ifdef OS2
#define INCL_DOS
#define INCL_VIO
#include <os2.h>
int vidhandle = 0; /* can be changed for AVIO */
void _fastcall set_screensize (int reservedbotlines,int reservedtoplines) {
VIOMODEINFO vm;
vm.cb = sizeof(VIOMODEINFO);
VioGetMode(&vm, vidhandle);
fakemaxx = vm.col;
fakemaxy = vm.row - reservedbotlines;
topy = reservedtoplines;
fakemaxy -= topy;
maxx = fakemaxx;
maxy = vm.row;
}
void _fastcall pos_hardcursor (int x,int y) {
VioSetCurPos(y,x,vidhandle);
}
void _fastcall hardcursor_off (void) {
VIOCURSORINFO vc;
VioGetCurType(&vc,vidhandle);
vc.attr = -1;
VioSetCurType(&vc,vidhandle);
}
void _fastcall hardcursor_on (int x,int y) {
VIOCURSORINFO vc;
VioGetCurType(&vc,vidhandle);
vc.attr = 0;
VioSetCurType(&vc,vidhandle);
VioSetCurPos(y,x,vidhandle);
}
void _fastcall put_char (char c, char attr, int x, int y) {
VioWrtCharStrAtt(&c,1,y,x,&attr,vidhandle);
}
void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr) {
int attrib = ' ' | (attr << 8);
VioScrollUp(ty,tx,by,bx,1,(char *)&attrib,vidhandle);
}
void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr) {
int attrib = ' ' | (attr << 8);
VioScrollUp(ty,tx,by,bx,-1,(char *)&attrib,vidhandle);
}
void _fastcall cleartoeol (int x,int y,int ex,char attr) {
int attrib = ' ' | (attr << 8);
VioScrollUp(y,x,y,ex,-1,(char *)&attrib,vidhandle);
}
void _fastcall validate_cursor (void) {
int x,y;
VioGetCurPos(&y,&x,vidhandle);
if(y > fakemaxy - 1) {
cury = fakemaxy - 1;
}
else cury = y;
curx = x;
}
void _fastcall get_hardcursorpos (int *x,int *y) {
VioGetCurPos(y,x,vidhandle);
}
#else
/* MS-DOS -- this stuff has _not_ been tested */
#include <dos.h>
#if !defined(MK_FP)
#define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off)))
#endif
static int far *vseg;
int maxy,maxx;
char usebios = 0; /* if true, output through BIOS */
int _fastcall vmode (void) {
union REGS r;
r.h.ah = 15;
r.x.bx = 0;
int86(0x10,&r,&r);
return r.h.al;
}
void _fastcall set_screensize (int reservedbotlines,int reservedtoplines) {
union REGS r;
unsigned int vbase;
r.h.ah = 0x0f;
r.x.bx = 0;
int86 (0x10, &r, &r);
fakemaxx = (int) r.h.ah;
if(fakemaxx < 80) { /* gimme a break! */
r.x.ax = 0x0003;
int86(0x10,&r,&r);
fakemaxx = 80;
}
maxx = fakemaxx;
r.x.ax = 0x1130;
r.x.dx = fakemaxy;
int86 (0x10, &r, &r);
maxy = fakemaxy = (r.x.dx == 0) ? 25 : (r.x.dx + 1);
fakemaxy -= reservedbotlines;
topy = reservedtoplines;
fakemaxy -= topy;
vbase = (vmode () == 7 ? 0xb000 : 0xb800);
vseg = MK_FP(vbase,0); /* address of video ram as pointer */
}
void _fastcall pos_hardcursor (int x,int y) {
union REGS r;
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((y << 8) & 0xff00) + x;
int86(0x10,&r,&r);
}
void _fastcall hardcursor_off (void) {
union REGS r;
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((maxy << 8) & 0xff00);
int86(0x10,&r,&r);
}
void _fastcall hardcursor_on (int x,int y) {
union REGS r;
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((y << 8) & 0xff00) + x;
int86(0x10,&r,&r);
}
void _fastcall put_char (char c, char attr, int x, int y) {
if(!usebios) {
register int far *v;
v = vseg + ((y * maxx) + x); /* point v to right spot in vid RAM */
*v = (c | (attr << 8)); /* display */
}
else {
union REGS r;
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((y << 8) & 0xff00) + x;
int86(0x10,&r,&r);
r.h.ah = 0x09;
r.h.bh = 0;
r.h.bl = attr;
r.x.cx = 1;
r.h.al = c;
int86(0x10,&r,&r);
}
}
void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr) {
union REGS r;
r.h.ah = 6;
r.h.al = 1;
r.h.bh = attr;
r.h.cl = tx;
r.h.ch = ty;
r.h.dl = bx;
r.h.dh = by;
int86(0x10,&r,&r);
}
void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr) {
union REGS r;
r.h.ah = 6;
r.h.al = 0;
r.h.bh = attr;
r.h.cl = tx;
r.h.ch = ty;
r.h.dl = bx;
r.h.dh = by;
int86(0x10,&r,&r);
}
void _fastcall cleartoeol (int x,int y,int ex,char attr) {
union REGS r;
r.h.ah = 6;
r.h.al = 0;
r.h.bh = attr;
r.h.cl = x;
r.h.ch = y;
r.h.dl = ex;
r.h.dh = y;
int86(0x10,&r,&r);
}
void _fastcall validate_cursor (void) {
union REGS r;
r.x.ax = 0x0300;
r.x.bx = 0;
int86(0x10,&r,&r);
if(r.h.dh > fakemaxy - 1) {
cury = fakemaxy - 1;
}
else cury = (int)r.h.dh;
curx = (int)r.h.dl;
}
int _fastcall dputs (int x,int y,char attr,char *s) {
int oldx,oldy;
char *p;
union REGS r;
if(s && s) {
r.x.ax = 0x0300;
r.x.bx = 0;
int86(0x10,&r,&r);
oldx = r.h.dl;
oldy = r.h.dh;
p = s;
while(*p) {
put_char(*p,attr,x,y);
x++;
p++;
}
r.x.ax = 0x0200;
r.x.bx = 0;
r.x.dx = ((oldy << 8) & 0xff00) + oldx;
int86(0x10,&r,&r);
}
return ((int)p - (int)s);
}
int dprintf (int x,int y,char attr,char *str,...) {
va_list ap;
static char buffer[318];
va_start (ap, str);
vsprintf (buffer, str, ap);
va_end (ap);
return dputs(x,y,attr,buffer);
}
void _fastcall get_hardcursorpos (int *x,int *y) {
union REGS r;
r.x.ax = 0x0300;
r.x.bx = 0;
int86(0x10,&r,&r);
*x = r.h.dl;
*y = r.h.dh;
}
#endif